home *** CD-ROM | disk | FTP | other *** search
/ Creative Computers / Creative Computers CD-ROM, Volume 1 (Legendary Design Technologies, Inc.)(1994).iso / shareware / fractals / mandelsquare / mandelsquare-1.06.lha / SaveAnim.c < prev    next >
C/C++ Source or Header  |  1992-12-20  |  8KB  |  352 lines

  1. /*
  2. **    MandelSquare - AmigaDOS 2.0/3.0 Mandelbrot set explorer
  3. **
  4. **    SaveAnim.c, Routines to save IFF-ANIM files
  5. **
  6. **    Copyright © 1991-1992 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10.     /* Animation information. */
  11.  
  12. struct AnimInfo
  13. {
  14.     struct IFFHandle    *Handle;
  15.     struct ViewPort        *VPort;
  16.     ULONG             ViewModes;
  17.     struct BitMap        *BitMaps[4],
  18.                 *Source;
  19.  
  20.     STRPTR             FileName;
  21.  
  22.     UWORD             Width,
  23.                  Height,
  24.                  Depth;
  25. };
  26.  
  27.     /* In skip.c */
  28.  
  29. extern UBYTE * __regargs    skip_comp_plane(UBYTE *in, UBYTE *last_in, UBYTE *out, WORD next_line, WORD rows);
  30. extern WORD __regargs        skip_count_plane(UBYTE *in, UBYTE *last_in, WORD next_line, WORD rows);
  31.  
  32.     /* In Packer.c */
  33.  
  34. extern LONG __regargs        PackRow(BYTE **pSource, BYTE **pDest, LONG rowSize);
  35.  
  36.     /* In ILBM.c */
  37.  
  38. extern VOID            FreeCustomBitMap(struct BitMap *BitMap,BYTE Standard);
  39. extern struct BitMap *        AllocCustomBitMap(UWORD Depth,UWORD Width,UWORD Height,BYTE Standard);
  40. extern BYTE            PutBitMap(struct IFFHandle *Handle,struct BitMap *BitMap);
  41. extern BYTE            PutViewModes(struct IFFHandle *Handle,struct ViewPort *VPort);
  42. extern BYTE            PutColourMap(struct IFFHandle *Handle,struct ViewPort *VPort);
  43. extern BYTE            PutBitMapHeader(struct IFFHandle *Handle,struct Screen *Screen);
  44.  
  45.     /* Local, static routines. */
  46.  
  47. STATIC VOID __regargs        FreeCustomBitMaps(struct AnimInfo *Info);
  48. STATIC BYTE __regargs        AllocCustomBitMaps(struct AnimInfo *Info);
  49. STATIC BYTE __regargs        PutDelta(struct IFFHandle *Handle,LONG *Data,LONG nData);
  50.  
  51.     /* Exported routines. */
  52.  
  53. VOID                CloseAnim(struct AnimInfo *Info,BYTE Success);
  54. struct AnimInfo *        OpenAnim(STRPTR Name,struct Screen *Screen);
  55. BYTE                AddAnim(struct AnimInfo *Info);
  56.  
  57.     /* FreeCustomBitMaps(struct AnimInfo *Info):
  58.      *
  59.      *    Free the four auxilary bitmaps.
  60.      */
  61.  
  62. STATIC VOID __regargs
  63. FreeCustomBitMaps(struct AnimInfo *Info)
  64. {
  65.     WORD i;
  66.  
  67.     for(i = 0 ; i < 4 ; i++)
  68.     {
  69.         if(Info -> BitMaps[i])
  70.             FreeCustomBitMap(Info -> BitMaps[i],TRUE);
  71.     }
  72. }
  73.  
  74.     /* AllocCustomBitMaps(struct AnimInfo *Info):
  75.      *
  76.      *    Allocate four auxilary bitmaps.
  77.      */
  78.  
  79. STATIC BYTE __regargs
  80. AllocCustomBitMaps(struct AnimInfo *Info)
  81. {
  82.     WORD i;
  83.  
  84.     for(i = 0 ; i < 4 ; i++)
  85.     {
  86.         if(!(Info -> BitMaps[i] = AllocCustomBitMap(Info -> Depth,Info -> Width,Info -> Height,TRUE)))
  87.         {
  88.             FreeCustomBitMaps(Info);
  89.  
  90.             return(FALSE);
  91.         }
  92.     }
  93.  
  94.     return(TRUE);
  95. }
  96.  
  97.     /* PutDelta(struct IFFHandle *Handle,LONG *Data,LONG DataSize):
  98.      *
  99.      *    Save the delta data to the file.
  100.      */
  101.  
  102. STATIC BYTE __regargs
  103. PutDelta(struct IFFHandle *Handle,LONG *Data,LONG DataSize)
  104. {
  105.     AnimationHeader Header;
  106.  
  107.         /* Reset the animation header contents. */
  108.  
  109.     memset(&Header,0,sizeof(AnimationHeader));
  110.  
  111.         /* Fill in compression information and relative
  112.          * timing information (1 jiffie = 1/60 second).
  113.          */
  114.  
  115.     Header . operation    = 5;
  116.     Header . reltime    = 1;
  117.  
  118.     if(!PushChunk(Handle,ID_ILBM,ID_FORM,IFFSIZE_UNKNOWN))
  119.     {
  120.         if(!PushChunk(Handle,0,ID_ANHD,sizeof(AnimationHeader)))
  121.         {
  122.             if(WriteChunkRecords(Handle,&Header,sizeof(AnimationHeader),1) == 1)
  123.             {
  124.                 if(!PopChunk(Handle))
  125.                 {
  126.                     if(!PushChunk(Handle,0,ID_DLTA,DataSize))
  127.                     {
  128.                         if(WriteChunkRecords(Handle,Data,DataSize,1) == 1)
  129.                         {
  130.                             if(!PopChunk(Handle))
  131.                             {
  132.                                 if(!PopChunk(Handle))
  133.                                     return(TRUE);
  134.                             }
  135.                         }
  136.                     }
  137.                 }
  138.             }
  139.         }
  140.     }
  141.  
  142.     return(FALSE);
  143. }
  144.  
  145.     /* CloseAnim(struct AnimInfo *Info,BYTE Success):
  146.      *
  147.      *    Close an animation file, freeing the auxilary data.
  148.      */
  149.  
  150. VOID
  151. CloseAnim(struct AnimInfo *Info,BYTE Success)
  152. {
  153.     if(Info -> Handle)
  154.     {
  155.         if(PopChunk(Info -> Handle))
  156.             Success = FALSE;
  157.  
  158.         CloseIFF(Info -> Handle);
  159.  
  160.         if(Info -> Handle -> iff_Stream)
  161.         {
  162.             if(!Close(Info -> Handle -> iff_Stream))
  163.                 Success = FALSE;
  164.         }
  165.         else
  166.             Success = TRUE;
  167.  
  168.         FreeIFF(Info -> Handle);
  169.     }
  170.  
  171.     FreeCustomBitMaps(Info);
  172.  
  173.     if(!Success)
  174.         DeleteFile(Info -> FileName);
  175.     else
  176.         SetProtection(Info -> FileName,FIBF_EXECUTE);
  177.  
  178.     FreeVec(Info);
  179. }
  180.  
  181.     /* OpenAnim(STRPTR Name,struct Screen *Screen):
  182.      *
  183.      *    Create an animation file.
  184.      */
  185.  
  186. struct AnimInfo *
  187. OpenAnim(STRPTR Name,struct Screen *Screen)
  188. {
  189.     struct AnimInfo    *Info;
  190.     WORD         Len = strlen(Name),
  191.              i;
  192.  
  193.         /* Allocate the auxilary buffer. */
  194.  
  195.     if(Info = (struct AnimInfo *)AllocVec(sizeof(struct AnimInfo) + Len + 1,MEMF_ANY | MEMF_CLEAR))
  196.     {
  197.             /* Fill in the header information. */
  198.  
  199.         Info -> FileName    = (STRPTR)(Info + 1);
  200.         Info -> VPort        = &Screen -> ViewPort;
  201.         Info -> Source        = Screen -> RastPort . BitMap;
  202.         Info -> ViewModes    = GetVPModeID(Info -> VPort);
  203.  
  204.         strcpy(Info -> FileName,Name);
  205.  
  206.         Info -> Width        = Screen -> Width;
  207.         Info -> Height        = Screen -> Height;
  208.         Info -> Depth        = Info -> Source -> Depth;
  209.  
  210.             /* Allocate the bitmaps. */
  211.  
  212.         if(AllocCustomBitMaps(Info))
  213.         {
  214.                 /* Copy the image information to all three bitmaps. */
  215.  
  216.             for(i = 0 ; i < 3 ; i++)
  217.                 BltBitMap(Info -> Source,0,0,Info -> BitMaps[i],0,0,Info -> Width,Info -> Height,0xC0,0xFF,NULL);
  218.  
  219.                 /* Set up the vanilla iff stuff... */
  220.  
  221.             if(Info -> Handle = AllocIFF())
  222.             {
  223.                 if(Info -> Handle -> iff_Stream = Open(Name,MODE_NEWFILE))
  224.                 {
  225.                     InitIFFasDOS(Info -> Handle);
  226.  
  227.                     if(!OpenIFF(Info -> Handle,IFFF_WRITE))
  228.                     {
  229.                             /* Set up the standard ANIM information. */
  230.  
  231.                         if(!PushChunk(Info -> Handle,ID_ANIM,ID_FORM,IFFSIZE_UNKNOWN))
  232.                         {
  233.                             if(!PushChunk(Info -> Handle,ID_ILBM,ID_FORM,IFFSIZE_UNKNOWN))
  234.                             {
  235.                                 if(PutBitMapHeader(Info -> Handle,Screen))
  236.                                 {
  237.                                     if(PutColourMap(Info -> Handle,Info -> VPort))
  238.                                     {
  239.                                         if(PutViewModes(Info -> Handle,Info -> VPort))
  240.                                         {
  241.                                             if(PutBitMap(Info -> Handle,Info -> BitMaps[0]))
  242.                                             {
  243.                                                 if(!PopChunk(Info -> Handle))
  244.                                                     return(Info);
  245.                                             }
  246.                                         }
  247.                                     }
  248.                                 }
  249.                             }
  250.                         }
  251.                     }
  252.                 }
  253.             }
  254.         }
  255.  
  256.         CloseAnim(Info,FALSE);
  257.     }
  258.  
  259.     return(NULL);
  260. }
  261.  
  262.     /* AddAnim(struct AnimInfo *Info):
  263.      *
  264.      *    Add another animation frame to the file.
  265.      */
  266.  
  267. BYTE
  268. AddAnim(struct AnimInfo *Info)
  269. {
  270.     struct BitMap    *Save;
  271.     LONG        *DeltaData,
  272.              DeltaCount,
  273.              PlaneCount[8],
  274.              PageSize,
  275.              RowBytes,
  276.              Rows,
  277.              j,i;
  278.     BYTE         Success = FALSE;
  279.  
  280.     UBYTE        *DeltaPtr,
  281.             *Planes[2];
  282.  
  283.         /* Move the bitmaps up. */
  284.  
  285.     Save = Info -> BitMaps[3];
  286.  
  287.     for(i = 3 ; i > 0 ; i--)
  288.         Info -> BitMaps[i] = Info -> BitMaps[i - 1];
  289.  
  290.     Info -> BitMaps[0] = Save;
  291.  
  292.         /* Copy the new screen bitmap to the first one in the list. */
  293.  
  294.     BltBitMap(Info -> Source,0,0,Save,0,0,Info -> Width,Info -> Height,0xC0,~0,NULL);
  295.  
  296.         /* Set up the startup information. */
  297.  
  298.     RowBytes    = Info -> BitMaps[1] -> BytesPerRow;
  299.     Rows        = Info -> BitMaps[1] -> Rows;
  300.     PageSize    = RowBytes * Rows;
  301.     DeltaCount    = 64;
  302.  
  303.         /* Determine the maximum buffer size required for compression. */
  304.  
  305.     for(i = 0 ; i < Info -> BitMaps[1] -> Depth ; i++)
  306.     {
  307.         Planes[0]    = Info -> BitMaps[1] -> Planes[i];
  308.         Planes[1]    = Info -> BitMaps[3] -> Planes[i];
  309.         PlaneCount[i]    = 0;
  310.         j        = PageSize;
  311.  
  312.         while(j--)
  313.         {
  314.             if(*Planes[0]++ != *Planes[1]++)
  315.             {
  316.                 PlaneCount[i]     = skip_count_plane(Info -> BitMaps[1] -> Planes[i],Info -> BitMaps[3] -> Planes[i],RowBytes,Rows);
  317.                 DeltaCount    += PlaneCount[i];
  318.  
  319.                 break;
  320.             }
  321.         }
  322.     }
  323.  
  324.         /* Allocate the compression buffer. */
  325.  
  326.     if(DeltaData = (LONG *)AllocVec(DeltaCount,MEMF_ANY | MEMF_CLEAR))
  327.     {
  328.         DeltaPtr    = (UBYTE *)&DeltaData[16];
  329.         DeltaCount    = 64;
  330.  
  331.             /* Compress the planes. */
  332.  
  333.         for(i = 0 ; i < Info -> BitMaps[1] -> Depth ; i++)
  334.         {
  335.             if(PlaneCount[i])
  336.             {
  337.                 DeltaData[i]     = DeltaCount;
  338.                 DeltaCount    += PlaneCount[i];
  339.                 DeltaPtr     = skip_comp_plane(Info -> BitMaps[1] -> Planes[i],Info -> BitMaps[3] -> Planes[i],DeltaPtr,RowBytes,Rows);
  340.             }
  341.         }
  342.  
  343.             /* Save the delta data to disk. */
  344.  
  345.         Success = PutDelta(Info -> Handle,DeltaData,DeltaCount);
  346.  
  347.         FreeVec(DeltaData);
  348.     }
  349.  
  350.     return(Success);
  351. }
  352.